package assist.datastore.dao;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Set;
import java.util.TreeSet;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import java.util.logging.Logger;

import assist.datastore.Datastore;
import assist.datastore.JDODatastore;
import assist.domain.model.Game;
import assist.domain.model.Player;
import assist.domain.model.RosterPlayer;
import assist.domain.model.Team;

public class GameDAO extends EntityDAO<Game>
{
    private static Logger logger = 
        Logger.getLogger(GameDAO.class.getName());       
    public GameDAO(Datastore<Game> datastore)
    {
        super(datastore, Game.class);
    }
    public Set<Game> getGames(Team team, Date start, Date end)
    {
        PersistenceManager pm = JDODatastore.getPersistenceManager();
        try
        {
            String teamId = team.getAbbreviation();
            Query query = pm.newQuery(Game.class);
            query.setFilter("(homeTeamId == homeParam || visitorTeamId == visParam) && date > startParam && date < endParam");
            query.declareParameters("String homeParam, String visParam, java.util.Date startParam, java.util.Date endParam");                      
            //query.setUnique(true);
                       
            logger.fine("Execute Games Query:" + team.getAbbreviation() + " From: " + start + "To: " + end);
            @SuppressWarnings("unchecked")
            Collection<Game> games = 
                (Collection<Game>) query.executeWithArray(new Object[]{teamId, teamId, start, end});
            Set<Game> gameSet = new TreeSet<Game>(); 
            logger.fine("Detaching Games" + games.size());
            for (Game game: games)
            {
                gameSet.add(pm.detachCopy(game));
            }
            logger.fine("Done Games" + gameSet.size());
            return gameSet;          
        }
        finally
        {
            pm.close();
        } 
    }

    
    public long getGamesPlayed(Set<Game> games, Player player)
    {
        PersistenceManager pm = JDODatastore.getPersistenceManager();
        try
        {        
        Collection<String> gameIds = new ArrayList<String>();        
        for(Game game: games)
        {
            gameIds.add(game.getId());
        }
        Query query = pm.newQuery("SELECT count(this) from " + RosterPlayer.class.getName());
        query.setFilter("gamesParam.contains(gameId) && player.playerId == playerParam");
        query.declareParameters("java.util.Collection gamesParam, Long playerParam");
        
        return (Long) query.execute(gameIds, player.getPlayerId());
        }
        finally
        {
            pm.close();
        } 
    }
    
    public Long getGamesPlayedTogether(Set<Game> games, Set<Player> players)
    {
        PersistenceManager pm = JDODatastore.getPersistenceManager();
        try
        {        
            Collection<String> gameIds = new ArrayList<String>();        
            for(Game game: games)
            {                
                gameIds.add(game.getId());
            }            
            String queryJDOQL = "SELECT count(distinct this.gameId) FROM " + RosterPlayer.class.getName() + " WHERE ";
            queryJDOQL += " :gamesParam.contains(gameId) ";
          //  queryJDOQL += " && (SELECT gameId FROM " + RosterPlayer.class.getName() + "  WHERE player.playerId == 8469466).contains(this.gameId)";
          //  queryJDOQL += " && (SELECT gameId FROM " + RosterPlayer.class.getName() + "  WHERE player.playerId == 8467423).contains(this.gameId)";
            
            
           
            for(Player player : players)
            {
                queryJDOQL += " && (SELECT gameId FROM " + RosterPlayer.class.getName() + " WHERE player.playerId == " + player.getPlayerId() + ").contains(this.gameId)";
             
            }
            Query query = pm.newQuery(queryJDOQL);
            //Query query = pm.newQuery("SELECT count(this.key) FROM " + RosterPlayer.class.getName() + " WHERE this.player.playerId == 8469466");
            return (Long) query.execute(gameIds);

        }
        finally
        {
            pm.close();
        } 
    }    


}
